package ymqtt

import (
	"context"
	"sync"
	"time"
)

const defaultDeviceExpire = 30 * time.Minute

type handle struct {
	*operate
	ctx     context.Context
	ttl     time.Duration
	ticker  *time.Ticker
	devices map[string]*device
}

func (h *handle) deviceGet(sn string) (d *device) {
	device, ok := h.devices[sn]
	if ok {
		d = device
	} else {
		h.Lock(func() {
			d = newDevice(h.ctx, sn)
			go d.start()
			h.devices[sn] = d
		})
	}

	return
}

func (h *handle) deviceDel(sn string) {
	if d, ok := h.devices[sn]; ok {
		h.Lock(func() {
			d.stop()
			delete(h.devices, sn)
		})
	}
}

func (h *handle) deviceClear() {
	h.Lock(func() {
		for _, d := range h.devices {
			d.stop()
		}
		h.devices = nil
	})
}

func (h *handle) deviceExpire() {
	for _ = range h.ticker.C {
		t := time.Now()
		for sn, d := range h.devices {
			if t.Sub(d.time) > h.ttl {
				h.deviceDel(sn)
			}
		}
	}
}

func newHandle(ctx context.Context) *handle {
	return &handle{
		operate: &operate{lock: sync.Mutex{}},
		ctx:     ctx,
		ttl:     defaultDeviceExpire,
		devices: make(map[string]*device),
	}
}
